﻿using Messenger.Lib;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace DA_SERVER
{
    [Serializable]
    class AccountFied
    {
        internal string password;
        internal string fullName;
        internal string IP;
        internal bool isLoggedIn;
        internal bool visible;
        internal ArrayList contacts;

        public AccountFied(string password, bool isLoggedIn, string fullName, string IP)
        {
            this.fullName = fullName;
            this.password = password;
            this.isLoggedIn = isLoggedIn;
            this.IP = IP;
            contacts = new ArrayList();
        }
    }
    
    [Serializable]
    public class Letter
        {
            string from;
            string to;
            string message;

            public Letter(string from, string to, string message)
            {
                this.from = from;
                this.to = to;
                this.message = message;
            }

            public string From
            {
                get
                {
                    return from;
                }
            }

            public string To
            {
                get
                {
                    return to;
                }
            }
            public string Message
            {
                get
                {
                    return message;
                }
            }
        }
        
    [Serializable]//Nhận một tham chiếu System.Object và một tham chiếu System.IO.Stream làm đối số
                  //tuần tự hóa Object và ghi nó vào Stream
    class XulyData
    {
        //Filed
        private Hashtable database;
        internal ArrayList offlineMessages;
        ArrayList letters = new ArrayList();
        // Lấy địa chỉ Ip của 1 username
        internal string GetIP(string username)
        {
            return ((AccountFied)database[username]).IP;
        }
        //Thêm người dùng vào database
        internal bool Add(string username, string password, string fullName, string IP)
        {
            //Nếu username tồn tại trong mảng băm thì false
            if (database.Contains(username))
                return false;
            database.Add(username, new AccountFied(password, false, fullName, IP));
            return Save();
        }
        //Xử lý đăng nhập
        internal bool SignIn(string username, string password, bool visible)
        {
            if (database.Contains(username))
            {
                if (((AccountFied)database[username]).password == password)
                {
                    ((AccountFied)database[username]).isLoggedIn = true;
                    ((AccountFied)database[username]).visible = visible;
                    Console.WriteLine(DateTime.Now.ToString() + ": " + username + " da dang nhap thanh cong!");
                    return true;
                }
                else
                {
                    return false;
                }
            }
            return false;
        }
        //Xử lý đăng xuất
        internal bool SignOut(string username)
        {
            if (database.Contains(username))
            {
                ((AccountFied)database[username]).isLoggedIn = false;
                ((AccountFied)database[username]).visible = false;
                Console.WriteLine(DateTime.Now.ToString() + ": " + username + " da thoat!");
                return true;
            }
            return false;
        }
        //Lấy mảng danh sách bạn bè của người dùng
        internal ArrayList GetContacts(string username) { 
            if(database.Contains(username)){
                return ((AccountFied)database[username]).contacts;
            }
            return null;
        }
        //Hiển thị tên đầy đủ người dùng
        internal string GetFullName(string username) {
            return ((AccountFied)database[username]).fullName;
        }
        //Thêm một liên hệ vào người dùng đã đăng nhập
        internal bool AddContact(string username,string contact) {
            if(database.Contains(username)){
                if (((AccountFied)database[username]).contacts.Contains(contact))
                    return false;
                if (database.Contains(contact))
                {
                    ((AccountFied)database[username]).contacts.Add(contact);
                    return Save();
                }
                
            }
            return false;
        }
        //Xử lý nick online offline
        internal bool IsVisible(string username)
        {
            if (database.Contains(username))
            {
                
                return ((AccountFied)database[username]).visible;
            }
            else
            {
                return false;
                //return true;
            }
        }
        // Kiểm tra sự tồn tại của người dùng
        internal bool ContactExists(string username)
        {
            return (database.Contains(username));
        }

        // Kiểm tra trạng thái "đã đăng nhập?"
        internal bool IsLoggedIn(string username)
        {
            if (database.Contains(username))
            {
                return ((AccountFied)database[username]).isLoggedIn;
            }
            else
            {
                return false;
            }
        }
        
        //Nhận messenger từ contact
        public LetterReceive Receive(string username)
        {
            int length = letters.Count;
            for (int i = 0; i < length; i++)
            {
                if (((Letter)letters[i]).To == username)
                {
                    LetterReceive lr = new LetterReceive(((Letter)letters[i]).Message, ((Letter)letters[i]).From);
                    letters.RemoveAt(i);
                    return lr;
                }
            }
            return new LetterReceive("", "");
        }
        //Đọc dữ liệu từ file
        internal bool LoadDataBase()
        {
            try
            {
                //Khởi tạo file database
                FileStream fileStream = new FileStream("UserInfo.txt", FileMode.Open);
                //Đối tượng BinaryFormatter được sử dụng cho quá trình tuần tự hóa nhị phân
                //BinaryFormatter sinh ra một stream nhị phân mô tả đối tượng và trạng thái của nó
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                //Định dạng đối tượng sang mảng byte
                //Deserialize nhận một tham chiếu Stream làm đối số,đọc dữ liệu của đối tượng được
                //tuần tự hóa từ Stream,và trả về một tham chiếu Object đến đối tượng được giải tuần tự hóa
                //Bạn phải ép tham chiếu Object này về kiểu thích hợp
                XulyData temp = (XulyData)binaryFormatter.Deserialize(fileStream);
                this.database = temp.database;
                fileStream.Close();
                return true;
            }
            catch
            {
                database = new Hashtable();
                return false;
            }
        }
        //Ghi dữ liệu lên file
        internal bool Save()
        {
            try
            {
                //Khởi tạo file database
                FileStream fileStream = new FileStream("UserInfo.txt", FileMode.Create);
                //Đối tượng BinaryFormatter được sử dụng cho quá trình tuần tự hóa nhị phân
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                binaryFormatter.Serialize(fileStream, this);
                fileStream.Close();
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return false;
            }
        }
    }
    
}
